package 排序;

import java.util.Arrays;
/*
希尔排序是基于插入排序的一种快速排序算法
插入排序的缺点：对于大规模的乱序数组排序速度慢
希尔排序简单的改变了插入排序：交换不相邻的元素以对数组的局部进行排序，
并最终用插入排序将局部有序的数组排序
 希尔排序对于大型数组排序效率很高，不需要额外的内存空间
  */
public class 希尔排序 {

    public static void shellSort(int[] a) {
        int n = a.length;
        // 设置增量，增量的取法有很多，这里是推荐取法
        // 插入排序的增量是1,属于相邻元素比较，现在换成不相邻元素比较
        int h = 1;
        while (h < n / 3) {
            h = 3 * h + 1;
        }
        // 增量最小为 1 ，也就是相邻的两个元素比较
        while (h >= 1) {

            // 对相聚 h 的两个元素使用插入排序
            for (int i = h; i < n; i++) {
                for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) {
                    exch(a, j, j-h);
                }
            }
            // 排序结束后，缩小增量，继续排序
            h /= 3;
        }
    }
    private static void exch(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static boolean less(Comparable v, Comparable w) {
        // 若 v 小于 w 则返回负数
        return v.compareTo(w) < 0;
    }

    public static void main(String[] args) {
//        int[] s = {3, -2, -1};
        int[] s = {9,7,1,-8,-1,-18,100};
        System.out.println(Arrays.toString(s));
        shellSort(s);
        System.out.println(Arrays.toString(s));

    }
}
